/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package view;

import controller.ControlManager;
import java.awt.AlphaComposite;
import java.awt.Color;

import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.HashMap;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.imageio.ImageIO;
import model.Cell;
import model.Map;
import model.Object;

/**
 *
 * @author Nevermade
 */
public class Canvas extends javax.swing.JPanel {

    /**
     * Creates new form Canvas
     */
    private ControlManager cM=MainWindow.man;;
    private int offset = 1;
    public Graphics2D g = null;    
    public int wOffset;
    public int tileH = 32;
    public int tileW = 64;
    public int nColumn;
    public int nRows;
    public int sobra = 51;
    public int grosor = 17;
    public int xHigh = 1;
    public int yHigh = 1;
    public BufferedImage offImg=null;
    public Graphics2D canvasGraphics=null;
    Image highLight = null;
    Map mapa=null;
    public int secX=0;
    public int secY=0;
    public int secW;
    public int secH;
    public int step=10;
    java.util.Map<String, BufferedImage> tiles = new HashMap<String, BufferedImage>();
    
    public void prepareCanvas(){
        xHigh = 1;
        yHigh = 1;
        secX=0;
        secY=0;
        mapa=cM.getMap();
        wOffset = (mapa.getRow() - 1) * ((int) tileW / 2);
        nColumn = mapa.getColumn();
        nRows = mapa.getRow();
        int width=MainWindow.man.getMap().getRow()*tileW;
        int height=MainWindow.man.getMap().getColumn()*tileH+sobra+grosor;
        System.out.println(width+" "+height);
        offImg=new BufferedImage(width,height,BufferedImage.TYPE_INT_ARGB);
        g=offImg.createGraphics();
        highLight = getImage("hl3");
        
        
    }
    
    @Override
    protected void paintComponent(Graphics gr) {
        super.paintComponent(gr);
        canvasGraphics = (Graphics2D)gr;       
        
        
        if (mapa != null && offImg!=null ) {
            g.clearRect(0, 0, offImg.getWidth(), offImg.getHeight());
            refreshCanvas(mapa); 
            resolveSectionDim();
            resolveSectionPos();            
            BufferedImage section = offImg.getSubimage(secX, secY, secW, secH);
            canvasGraphics.drawImage(section,0,0,this);
            MainWindow.mMap.repaint();
        }

    }
    public void resolveSectionDim(){
        secH=getHeight();
        secW=getWidth(); 
        
        if(secH>offImg.getHeight())secH=offImg.getHeight();
        else if(secW>offImg.getWidth())secW=offImg.getWidth();
        
    }
    public void resolveSectionPos(){
       
        if(secX<0)secX=0;
        else if(secY<0)secY=0;
        else if (secX>offImg.getWidth()-secW)
            secX=offImg.getWidth()-secW;
        else if (secY>offImg.getHeight()-secH)secY=offImg.getHeight()-secH;
    }
    public BufferedImage getImage(String name) {
        BufferedImage img = tiles.get(name);
        if (img == null) {
            try {
                img = ImageIO.read(getClass().getResource("/" + name + ".png"));
            } catch (IOException ex) {
                Logger.getLogger(Canvas.class.getName()).log(Level.SEVERE, null, ex);
            }
            tiles.put(name, img);
        }
        return img;
    }

    public void drawCell(Cell c, int i, int j) {
        int terreno = c.getType();
        BufferedImage img;
        switch (terreno) {
            case 0:

                img = getImage("basic1");
                g.drawImage(img, wOffset + (i * tileW / 2) - (j * (tileW / 2)), j * (tileH) / 2 + i * ((tileH) / 2), null);

                break;
            case 1:

                img = getImage("ground");
                g.drawImage(img, wOffset + (i * tileW / 2) - (j * (tileW / 2)), j * (tileH) / 2 + i * ((tileH) / 2), null);


                break;
            /*case 2:
             try {
             g.drawImage(ImageIO.read(getClass().getResource("/basic1.png")), wOffset + (i * tileW / 2) - (j * (tileW / 2)), j * (tileH) / 2 + i * ((tileH) / 2), null);

             } catch (IOException ex) {
             Logger.getLogger(Canvas.class.getName()).log(Level.SEVERE, null, ex);
             }
             break;*/
        }

        if (i == xHigh - 1 && j == yHigh - 1) {
            
            g.drawImage(highLight, wOffset + (i * tileW / 2) - (j * (tileW / 2)), j * (tileH) / 2 + i * ((tileH) / 2), null);
            //g.drawImage(getTile(c),wOffset + (i * tileW / 2) - (j * (tileW / 2)), j * (tileH) / 2 + i * ((tileH) / 2), null);
            if(MainWindow.selImg!=null){
                float opacity=0.5f;
                g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, opacity));
                g.drawImage(MainWindow.selImg, wOffset + (i * tileW / 2) - (j * (tileW / 2)), j * (tileH) / 2 + i * ((tileH) / 2), null);
                opacity=1f;
                g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, opacity));
            }else{
                
                g.drawImage(getTile(c), wOffset + (i * tileW / 2) - (j * (tileW / 2)), j * (tileH) / 2 + i * ((tileH) / 2), null);
                
            }
        }else
            g.drawImage(getTile(c), wOffset + (i * tileW / 2) - (j * (tileW / 2)), j * (tileH) / 2 + i * ((tileH) / 2), null);
        
    }

    public void drawHighLight(int i, int j) {

        g.drawImage(highLight, wOffset + (i * tileW / 2) - (j * (tileW / 2)), j * (tileH) / 2 + i * ((tileH) / 2), null); //wOffset + (i * tileW / 2) - (j * (tileW / 2)), j * (tileH) / 2 + i * ((tileH) / 2), null);
        
        //repaint(wOffset + (i * tileW / 2) - (j * (tileW / 2)), j * (tileH) / 2 + i * ((tileH) / 2),tileW,tileH+sobra+grosor);

    }

    public void refreshCanvas(Map mapa) {
        int x = mapa.getColumn();
        int y = mapa.getRow();
        int u = xHigh - 1;
        int v = yHigh - 1;

        for (int j = 0; j < y; j++) {
            for (int i = 0; i < x; i++) {
                Cell c = mapa.getCell(i, j);
                drawCell(c, i, j);

            }

        }
    }

    public BufferedImage getTile(Cell c) {
        BufferedImage img = null;
        Object o = c.getObject();



        if (o != null) {    //dibujar el objeto seleccionado
            String name = o.getName();
            if (c.getObject().getName().equals("Casa1")) {
                img = getImage("house2");
            } else if (c.getObject().getName().equals("Casa2")) {
                img = getImage("house1");
            } else if (c.getObject().getName().equals("Camino1")) {
                img = getImage("path_ew");
            } else if (c.getObject().getName().equals("Camino2")) {
                img = getImage("path_ns");
            } else if (c.getObject().getName().equals("Camino3")) {
                img = getImage("path_sw");
            } else if (c.getObject().getName().equals("Camino4")) {
                img = getImage("path_ne");
            } else if (c.getObject().getName().equals("Camino5")) {
                img = getImage("path_nw");
            } else if (c.getObject().getName().equals("Camino6")) {
                img = getImage("road_se");
            } else if (c.getObject().getName().equals("Camino7")) {
                img = getImage("path_sew");
            } else if (c.getObject().getName().equals("Camino8")) {
                img = getImage("path_nse");
            } else if (c.getObject().getName().equals("Camino9")) {
                img = getImage("road_nsew");
            } else if (c.getObject().getName().equals("Arbol1")) {
                img = getImage("trees13");
            } else if (c.getObject().getName().equals("Arbol2")) {
                img = getImage("trees18");
            } else if (c.getObject().getName().equals("Arbol3")) {
                img = getImage("trees12");
            }
        }

        return img;
    }

    public boolean perteneceMapa(int x, int y) {
        x+=secX;
        y+=secY;
        double fx1, fx2, fx3, fx4;
        if (x >= 0 && x <= nRows * tileW && y >= sobra && y <= (sobra + nColumn * tileH)) {
            //f1
            fx1 = (-1 * (double) (tileH) / tileW) * x + ((tileH) / 2) * nColumn + sobra;
            //f2
            fx2 = ((double) (tileH) / tileW) * (x - ((tileW / 2) * nRows)) + sobra;
            //f3
            fx3 = ((double) (tileH) / tileW) * x + ((tileH) / 2) * nColumn + sobra;
            //f4
            fx4 = (-1 * (double) (tileH) / tileW) * (x - (tileW * nRows)) + sobra+ ((tileH) / 2) * nColumn;

            if (y <= fx3 && y <= fx4 && y >= fx1 && y >= fx2) {
                return true;
            } else {
                return false;
            }

        } else {
            return false;
        }


    }

    public void getCellPos(int x, int y) {//cambioCoord
        
        
        double xp, yp;
        x+=secX;
        y+=secY;
        int y2 = y - 51;
        int x2 = x - (tileW/2*nRows);//x-(tileW/2*nRows);

        int det = ((tileH / 2) * (-tileW / 2)) - ((tileH / 2) * (tileW / 2));
        xp = ((-32 * y2) - (16 * x2)) / det;
        yp = ((16 * x2) - (32 * y2)) / det;
        MainWindow.coordX.setText(Integer.toString((int) xp + 1));
        MainWindow.coordY.setText(Integer.toString((int) yp + 1));

        /*
         double k=Math.sin(av);
         double det=(-1.0)/(k*k);
        
        
         xp= ((-((Math.sin(teta)/k))*y2)-((Math.cos(teta)/k)*x2))/det;
         yp=(((Math.sin(teta)/k)*x2)-((Math.cos(teta)/k)*y2))/det;
         */

        /*
         xp= (Math.sin(1.5707)*0)+(Math.cos(1.5707)*1);
         yp=(-1*Math.sin(1.5707)*1)+(Math.cos(1.5707)*0);
         *//*
         MainWindow.coordX.setText(Double.toString(xp));
         MainWindow.coordY.setText(Double.toString(yp));
         */
        /*
         double tileIsoM=Math.sqrt(Math.pow(tileW/2,2)+Math.pow(tileH/2,2));
         MainWindow.coordX.setText(Double.toString((xp/tileIsoM)));
         MainWindow.coordY.setText(Double.toString((yp/tileIsoM)));
         */
    }

    public void repintar(int i, int j) {
        //repaint();
        repaint(wOffset-secX + (i * tileW / 2) - (j * (tileW / 2)), j * (tileH) / 2 + i * ((tileH) / 2)-secY, tileW, tileH + sobra + grosor);
        //repaint(wOffset + ((i+1) * tileW / 2) - (j * (tileW / 2)), j * (tileH) / 2 + (i+1) * ((tileH) / 2),tileW,tileH+sobra+grosor);
        //repaint(wOffset + (i * tileW / 2) - ((j+1) * (tileW / 2)), (j+1) * (tileH) / 2 + i * ((tileH) / 2),tileW,tileH+sobra+grosor);
        //repaint(wOffset + ((i+1) * tileW / 2) - ((j+1) * (tileW / 2)), (j+1) * (tileH) / 2 + (i+1) * ((tileH) / 2),tileW,tileH+sobra+grosor);
    }
    
    
    public Canvas() {
        prepareCanvas();
        initComponents();
        
    }

    /**
     * This method is called from within the constructor to initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is always
     * regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
        this.setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 509, Short.MAX_VALUE)
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 302, Short.MAX_VALUE)
        );
    }// </editor-fold>//GEN-END:initComponents
    // Variables declaration - do not modify//GEN-BEGIN:variables
    // End of variables declaration//GEN-END:variables
}